package club.kynb.mall.application.context;

import club.kynb.mall.application.model.model.dto.UserReceiveCouponDTO;
import club.kynb.mall.application.model.model.vo.OrderPreviewResultVO;
import club.kynb.mall.order.model.dto.ShoppingCartDTO;
import club.kynb.mall.product.dto.ProductSkuDTO;
import club.kynb.mall.product.dto.ProductSpuDetailDTO;
import club.kynb.mall.user.model.dto.ShippingAddressDTO;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import lombok.Data;
import org.pizza.model.Command;
import org.pizza.model.Model;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author kynb_club@163.com
 * @since 2021/7/5 4:58 下午
 */
@Data
public class OrderPreviewContext implements Model ,OrderContext{
    /**
     * 选中的购物车
     */
    private List<ShoppingCartDTO> checkedList;
    /**
     * 价格过滤后的spu列表
     */
    private List<ProductSpuDetailDTO> filteredSpuList;
    /**
     * 可使用的的优惠券
     */
    private List<UserReceiveCouponDTO> userCouponList;
    /**
     * 收货地址列表
     */
    private List<ShippingAddressDTO> shippingAddressList;
    /**
     * 订单预览结果
     */
    private OrderPreviewResultVO orderPreviewResultVO = new OrderPreviewResultVO();

    /**
     * 公共算法
     *
     * @return 总金额
     */
    public BigDecimal calculateTotalAmount(List<ProductSpuDetailDTO> spuList, List<ShoppingCartDTO> checkedList) {
        if (CollectionUtil.isEmpty(spuList)) {
            return BigDecimal.ZERO;
        }
        final List<ProductSkuDTO> skuList = spuList.stream().flatMap(productSpuDTO -> productSpuDTO.getSkuList().stream()).collect(Collectors.toList());
        final Map<String, ProductSkuDTO> skuMap = skuList.stream().collect(Collectors.toMap(ProductSkuDTO::getId, productSkuDTO -> productSkuDTO, (p1, p2) -> p2));
        //计算商品总价
        return checkedList.stream().map(cartDTO -> {
            final ProductSkuDTO productSkuDTO = skuMap.get(cartDTO.getSkuId());
            return NumberUtil.mul(productSkuDTO.getSkuPrice(), new BigDecimal(String.valueOf(cartDTO.getSkuNum())));
        }).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    @Override
    public Command getCommand() {
        return new Command() {
            @Override
            public boolean check(boolean isThrow) {
                return super.check(isThrow);
            }
        };
    }
}
